from kivy.clock import Clock
from kivy.core.audio import SoundLoader
from kivy.properties import ObjectProperty, StringProperty
from kivy.uix.popup import Popup
from kivy.uix.widget import Widget

from common import SoundSham, SoundLoaderPygame
from ui.audio_player.base_weight import TogglePlayBehavior, MyFileChooser
from ui.base import UIMix

SOUND_LOADER_TYPE = 'pygame'  # pygame or default


class PlayBase(TogglePlayBehavior, Widget, UIMix):
    file_path = StringProperty()
    sound = ObjectProperty()

    def __init__(self, **kwargs):
        """
            主要的音轨播放行
        :param kwargs:
        """
        self.updater = None  # 定时器 更新播放进度滑块
        self.auto_move_slider = False  # 在操作滑块的过程中 不需要自动移动滑块
        self.seek_value = 0  # 当前播放时间
        self._popup = None  # 文件选择弹窗
        self.get_file_path_count = 0
        super().__init__(**kwargs)

    def _sound_load(self, file_path):
        if SOUND_LOADER_TYPE == 'pygame':
            self.sound = SoundLoaderPygame.load(file_path)
        else:
            self.sound = SoundLoader.load(file_path)

    def _sound_length(self):
        return self.sound.length

    def _sound_play(self):
        self.sound.play()

    def _sound_stop(self):
        self.sound.stop()

    def _sound_seek(self, seek_value):
        self.sound.seek(seek_value)

    def _sound_state(self):
        return self.sound.state

    def init_slider(self):
        self._sound_load(self.file_path)
        self.on_sound_load()

    def start_play(self):
        if self.sound is None or self._sound_length() == 0:
            return
        self._toggle_do_play()
        self._sound_play()
        if self.updater:
            self.updater()
        else:
            self.init_updater()

    def init_updater(self):
        if self.updater is None:
            self.updater = Clock.schedule_interval(lambda dt: self.update_slider(), 0.2)

    def update_slider(self):
        if not self.auto_move_slider and self.is_playing():
            self.seek_value = self.sound.get_pos()
            self.on_updater_ui()

        if self._sound_state() == 'stop':
            self.updater.cancel()
            self.updater = None
            # 如果音乐正常播放完毕, 重置播放
            if self._sound_length() - self.seek_value < 1 or self.seek_value == 0:
                self.seek_value = 0
                self._toggle_do_stop()
                self.on_play_completed_update_ui()

    def on_updater_ui(self):
        """定时器更新其他ui"""

    def on_play_completed_update_ui(self):
        """完整播放完毕时更新UI"""

    def on_slider_touch_up(self, widget, touch):
        if touch.grab_current == widget and self.sound:
            self.seek_value = widget.max * widget.value_normalized
            self._sound_seek(self.seek_value)

        self.auto_move_slider = False

    def on_slider_touch_down(self, widget, touch):
        if widget.collide_point(*touch.pos):
            self.auto_move_slider = True

    def clear_audio(self):
        """清空音频"""
        self.stop_play()
        self.sound = SoundSham()
        self.file_path = "None"
        self._reset()

    def _reset(self):
        self.seek_value = 0
        self.on_clear_audio_update_ui()
        self._toggle_do_stop()

    def on_clear_audio_update_ui(self):
        """清空音频更新UI"""

    def add_audio(self):
        """添加音频"""
        content = MyFileChooser(load=self.add_audio_load, cancel=self.dismiss_popup)
        self._popup = Popup(title='选择音频文件',
                            content=content, size_hint=(0.9, 0.9))
        self._popup.open()

    def add_audio_load(self, selection):
        if selection and isinstance(selection, list):
            file_path = selection[-1]
            self.stop_play()
            self._sound_load(file_path)
            self._reset()
            self.file_path = file_path
            self.on_sound_load()
        self.dismiss_popup()

    def on_sound_load(self):
        """选择新文件时触发"""

    def dismiss_popup(self):
        self._popup.dismiss()

    def is_playing(self):
        return self.sound and self._sound_state() == 'play'

    def stop_play(self):
        if self.sound and self.is_playing():
            self._sound_stop()

    def on_fast_rewind(self):
        """快退"""
        if self.is_playing():
            self._sound_seek(self.seek_value - 10)

    def on_pause_or_proceed(self):
        """暂停或者继续"""
        if self.sound is None:
            return
        if round(self.seek_value, 2) == round(self._sound_length(), 2):
            return

        if self.is_playing():  # 暂停
            self._toggle_do_pause()
            self.stop_play()
        else:  # 继续播放
            self.proceed_play()
        self.on_pause_or_proceed_update_ui()

    def proceed_play(self):
        self._sound_seek(self.seek_value)
        self.start_play()

    def on_pause_or_proceed_update_ui(self):
        """暂停或者继续更新UI"""

    def on_fast_forward(self):
        """快进"""
        if self.is_playing():
            self._sound_seek(self.seek_value + 10)
